<?php


namespace app\api\controller;


use app\BaseController;
//use app\common\service\CommonObjectStorageService;
use app\Response;
use think\facade\Config;
use think\facade\Env;
use think\facade\Filesystem;
use think\facade\Request;
use Qcloud\Cos\Client;

class Uploads extends BaseController
{

    public function bigUploads()
    {
        header("Access-Control-Allow-origin:*");
        header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
        header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
        header("Cache-Control: no-store, no-cache, must-revalidate");
        header("Cache-Control: post-check=0, pre-check=0", false);
        header("Pragma: no-cache");
        if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
            exit; // finish preflight CORS requests here
        }
        if (!empty($_REQUEST['debug'])) {
            $random = rand(0, intval($_REQUEST['debug']));
            if ($random === 0) {
                header("HTTP/1.0 500 Internal Server Error");
                exit;
            }
        }
        // 5 minutes execution time
        @set_time_limit(5 * 60);
        $targetDir = app()->getRootPath() . "/public/uploads/liveVideo_upload_tmp/";   //切片保留路径

        $cleanupTargetDir = true; // Remove old files
        $maxFileAge = 5 * 3600; // Temp file age in seconds
        // Create target dir
        if (!file_exists($targetDir)) {
            @mkdir($targetDir);
        }
        // Get a file name
        if (isset($_REQUEST["name"])) {
            $fileName = $_REQUEST["name"];
        } elseif (!empty($_FILES)) {
            $fileName = $_FILES["file"]["name"];
        } else {
            $fileName = uniqid("file_");
        }
        if(strpos("http")){
            $fileName = str_replace();
        }
        $filePath = $targetDir . DIRECTORY_SEPARATOR . $fileName;
        // Chunking might be enabled
        $chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0;
        $chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 1;
        // Remove old temp files
        if ($cleanupTargetDir) {
            if (!is_dir($targetDir) || !$dir = opendir($targetDir)) {
                return json(['code' => 0, 'msg' => lang('Failed to open temp directory!'.$filePath), 'data' => '', 'count' => '']);
            }
            while (($file = readdir($dir)) !== false) {
                $tmpfilePath = $targetDir . DIRECTORY_SEPARATOR . $file;
                // If temp file is current file proceed to the next
                if ($tmpfilePath == "{$filePath}_{$chunk}.part" || $tmpfilePath == "{$filePath}_{$chunk}.parttmp") {
                    continue;
                }
                // Remove temp file if it is older than the max age and is not the current file
                if (preg_match('/\.(part|parttmp)$/', $file) && (@filemtime($tmpfilePath) < time() - $maxFileAge)) {
                    @unlink($tmpfilePath);
                }
            }
            closedir($dir);
        }

        // Open temp file
        if (!$out = @fopen("{$filePath}_{$chunk}.parttmp", "wb")) {
            return json(['code' => 0, 'msg' => lang('Failed to open output stream!'.$filePath), 'data' => '', 'count' => '']);
        }
        var_dump("{$filePath}_{$chunk}.parttmp");

        if (!empty($_FILES)) {
            if ($_FILES["file"]["error"] || !is_uploaded_file($_FILES["file"]["tmp_name"])) {
                return json(['code' => 0, 'msg' => lang('Failed to move uploaded file!'), 'data' => '', 'count' => '']);
            }

            // Read binary input stream and append it to temp file
            if (!$in = @fopen($_FILES["file"]["tmp_name"], "rb")) {
                return json(['code' => 0, 'msg' => lang('Failed to open input stream1!'), 'data' => '', 'count' => '']);
            }
        } else {
            if (!$in = @fopen("php://input", "rb")) {
                return json(['code' => 0, 'msg' => lang('Failed to open input stream2!'), 'data' => '', 'count' => '']);
            }
        }

        while ($buff = fread($in, 4096)) {
            fwrite($out, $buff);
        }

        @fclose($out);
        @fclose($in);

        rename("{$filePath}_{$chunk}.parttmp", "{$filePath}_{$chunk}.part");

        $index = 0;
        $done = true;
        for ($index = 0; $index < $chunks; $index++) {
            if (!file_exists("{$filePath}_{$index}.part")) {
                $done = false;
                break;
            }
        }
        if ($done) {
            $dir = date('Ymd');
            $uploadDir = app()->getRootPath().'/public/uploads/liveVideo/'.$dir;       //最终上传路径

            if (!file_exists($uploadDir)) {
                @mkdir($uploadDir,7777);
                @chmod( $uploadDir,0777);
            }
            $save_name = strtolower($this->str_random(20)).uniqid();//随机一个存储文件名
            $extension = Request::param("extension","");
            if(empty($extension)){
                $extension = pathinfo($fileName)['extension'];
            }
            $uploadPath = $uploadDir . DIRECTORY_SEPARATOR . $save_name . '.' . $extension;
            $file_save_path = $dir . '/' . $save_name . '.' . $extension;
            if (!$out = @fopen($uploadPath, "wb")) {
                return json(['code' => 0, 'msg' => lang('Failed to open input stream3!'), 'data' => '', 'count' => '']);
            }

            if (flock($out, LOCK_EX)) {
                for ($index = 0; $index < $chunks; $index++) {
                    if (!$in = @fopen("{$filePath}_{$index}.part", "rb")) {
                        break;
                    }

                    while ($buff = fread($in, 4096)) {
                        fwrite($out, $buff);
                    }
                    @fclose($in);
                    @unlink("{$filePath}_{$index}.part");
                }
                flock($out, LOCK_UN);
            }
            @fclose($out);
            $data = ['file_path' => $file_save_path, 'file_name' => $fileName];
            $srcPathFile = \think\facade\Filesystem::getDiskConfig('public', 'root') . '/' . str_replace('\\', '/', "uploads/liveVideo/".$file_save_path);
            $srcPath = Config::get("objectstorage.mooka_video");//本地文件绝对路径
            $res = \app\common\service\CommonObjectStorageService::uploadImages($srcPathFile,'video/mp4',$srcPath,$extension);
            $res = (array)json_decode($res);
            if($res["code"] == 0){
                $file = $srcPathFile;
                if(file_exists($file)){
                    @unlink($file);
                }
                $domain = Config::get("objectstorage.domain_name");
                $res["data"] = str_replace($domain,"/",$res["data"]);
                return Response::wrapData($res["data"]);
            }else{
                return Response::wrapError($res["msg"]);
            }
        }
    }

    public function icValueVideoUploads()
    {
        header("Access-Control-Allow-origin:*");
        header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
        header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
        header("Cache-Control: no-store, no-cache, must-revalidate");
        header("Cache-Control: post-check=0, pre-check=0", false);
        header("Pragma: no-cache");
        if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
            exit; // finish preflight CORS requests here
        }
        if (!empty($_REQUEST['debug'])) {
            $random = rand(0, intval($_REQUEST['debug']));
            if ($random === 0) {
                header("HTTP/1.0 500 Internal Server Error");
                exit;
            }
        }
        // 5 minutes execution time
        @set_time_limit(5 * 60);
        $targetDir = app()->getRootPath() . "/public/uploads/icValueVideo_tmp/";   //切片保留路径

        $cleanupTargetDir = true; // Remove old files
        $maxFileAge = 5 * 3600; // Temp file age in seconds
        // Create target dir
        if (!file_exists($targetDir)) {
            @mkdir($targetDir);
        }
        // Get a file name
        if (isset($_REQUEST["name"])) {
            $fileName = $_REQUEST["name"];
        } elseif (!empty($_FILES)) {
            $fileName = $_FILES["file"]["name"];
        } else {
            $fileName = uniqid("file_");
        }
        $filePath = $targetDir . DIRECTORY_SEPARATOR . $fileName;
        // Chunking might be enabled
        $chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0;
        $chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 1;
        // Remove old temp files
        if ($cleanupTargetDir) {
            if (!is_dir($targetDir) || !$dir = opendir($targetDir)) {
                return json(['code' => 0, 'msg' => lang('Failed to open temp directory!'), 'data' => '', 'count' => '']);
            }
            while (($file = readdir($dir)) !== false) {
                $tmpfilePath = $targetDir . DIRECTORY_SEPARATOR . $file;
                // If temp file is current file proceed to the next
                if ($tmpfilePath == "{$filePath}_{$chunk}.part" || $tmpfilePath == "{$filePath}_{$chunk}.parttmp") {
                    continue;
                }
                // Remove temp file if it is older than the max age and is not the current file
                if (preg_match('/\.(part|parttmp)$/', $file) && (@filemtime($tmpfilePath) < time() - $maxFileAge)) {
                    @unlink($tmpfilePath);
                }
            }
            closedir($dir);
        }

        // Open temp file
        if (!$out = @fopen("{$filePath}_{$chunk}.parttmp", "wb")) {
            return json(['code' => 0, 'msg' => lang('Failed to open output stream!'), 'data' => '', 'count' => '']);
        }

        if (!empty($_FILES)) {
            if ($_FILES["file"]["error"] || !is_uploaded_file($_FILES["file"]["tmp_name"])) {
                return json(['code' => 0, 'msg' => lang('Failed to move uploaded file!'), 'data' => '', 'count' => '']);
            }

            // Read binary input stream and append it to temp file
            if (!$in = @fopen($_FILES["file"]["tmp_name"], "rb")) {
                return json(['code' => 0, 'msg' => lang('Failed to open input stream1!'), 'data' => '', 'count' => '']);
            }
        } else {
            if (!$in = @fopen("php://input", "rb")) {
                return json(['code' => 0, 'msg' => lang('Failed to open input stream2!'), 'data' => '', 'count' => '']);
            }
        }

        while ($buff = fread($in, 4096)) {
            fwrite($out, $buff);
        }

        @fclose($out);
        @fclose($in);

        rename("{$filePath}_{$chunk}.parttmp", "{$filePath}_{$chunk}.part");

        $index = 0;
        $done = true;
        for ($index = 0; $index < $chunks; $index++) {
            if (!file_exists("{$filePath}_{$index}.part")) {
                $done = false;
                break;
            }
        }
        if ($done) {
            $dir = date('Ymd');
            $uploadDir = app()->getRootPath().'/public/uploads/icValueVideo/'.$dir;       //最终上传路径

            if (!file_exists($uploadDir)) {
                @mkdir($uploadDir,7777);
                @chmod( $uploadDir,0777);
            }
            $save_name = strtolower($this->str_random(20)).uniqid();//随机一个存储文件名

            $extension = Request::param("extension","");
            if(empty($extension)){
                $extension = pathinfo($fileName)['extension'];
            }
            $uploadPath = $uploadDir . DIRECTORY_SEPARATOR . $save_name . '.' . $extension;
            $file_save_path = $dir . '/' . $save_name . '.' . $extension;
            if (!$out = @fopen($uploadPath, "wb")) {
                return json(['code' => 0, 'msg' => lang('Failed to open input stream3!'), 'data' => '', 'count' => '']);
            }

            if (flock($out, LOCK_EX)) {
                for ($index = 0; $index < $chunks; $index++) {
                    if (!$in = @fopen("{$filePath}_{$index}.part", "rb")) {
                        break;
                    }

                    while ($buff = fread($in, 4096)) {
                        fwrite($out, $buff);
                    }
                    @fclose($in);
                    @unlink("{$filePath}_{$index}.part");
                }
                flock($out, LOCK_UN);
            }
            @fclose($out);
            $data = ['file_path' => $file_save_path, 'file_name' => $fileName];
            $srcPathFile = \think\facade\Filesystem::getDiskConfig('public', 'root') . '/' . str_replace('\\', '/', "uploads/liveVideo/".$file_save_path);
            $srcPath = Config::get("objectstorage.user_order_video");//本地文件绝对路径
            $res = \app\common\service\CommonObjectStorageService::uploadImages($srcPathFile,'video/mp4',$srcPath,$extension);
            $res = (array)json_decode($res);
            if($res["code"] == 0){
                $file = $srcPathFile;
                if(file_exists($file)){
                    @unlink($file);
                }
                $domain = Config::get("objectstorage.domain_name");
                $res["data"] = str_replace($domain,"/",$res["data"]);
                return Response::wrapData($res["data"]);
            }else{
                return Response::wrapError($res["msg"]);
            }
        }
    }

    public function upload($file = '')
    {
        if(empty($file))
            $file = request()->file('file');
        if($file)
        {
            if(is_array($file)){
                $data = [];
                foreach ($file as $item) {
                    $savename = Filesystem::disk('public')->putFile('uploads/mooka', $file);
                    if($savename){
                        // 成功上传后 获取上传信息
                        $save_name = str_replace('\\','/',$savename);
                        $name = $file->getOriginalName();
                        $size = $file->getSize();
                        list($width, $height, $type) = getimagesize(Env::get('root_path').$save_name);
                        $cell = [
                            'save_name' => $save_name,
                            'name' => $name,
                            'width'=>$width,
                            'height'=>$height,
                            'size'=>$size
                        ];
                        array_push($data,$cell);
                    }
                    return Response::wrapData($data);
                }
            }else{
                // 移动到框架应用根目录/uploads/ 目录下
                $savename = Filesystem::disk('public')->putFile('uploads/mooka', $file);
                if($savename){
//                    $save_name = $file->getOriginalName();
                    $save_name = str_replace('\\','/',$savename);
                    $name = $file->getOriginalName();
                    $size = $file->getSize();
                    list($width, $height, $type) = getimagesize(Env::get('root_path').$save_name);
                    $data = [
                        'save_name' => $save_name,
                        'name' => $name,
                        'width'=>$width,
                        'height'=>$height,
                        'size'=>$size
                    ];
                    return Response::wrapData($data);
                }else{
                    return Response::wrapError(lang($file->getError()));
                }
            }

        }else{
            return Response::wrapError("文件不存在");
        }

    }

    public function delPic($pic)
    {
        if(!empty($pic))
        {
            $file = Env::get('root_path').$pic;
            if(file_exists($file))
                unlink($file);
        }
    }

    public function cosUploadsMookaImages(){
        $file = request()->file('file');
        $srcPath = Config::get("objectstorage.mooka_img");//本地文件绝对路径
        try {
            validate(['image'=>'filesize:10240|fileExt:jpg,png,jpeg'])
                ->check([$file]);
            if($file){
                //传临时目录以及mime类型以及创建远程目录
                $res = \app\common\service\CommonObjectStorageService::uploadImages($file->getPathname(),$file->getMime(),$srcPath,$file->extension());

            }else{
                return Response::wrapError($file->getError(),-1);
            }
        } catch (\think\exception\ValidateException $e) {
            return Response::wrapError($file->getError(),-1);
        }
        if (isset($res)){
            $res = (array)json_decode($res);
            if($res["code"] == 0){
                $domain = Config::get("objectstorage.domain_name");
                $res["data"] = str_replace($domain,"/",$res["data"]);
                return Response::wrapData($res["data"]);
            }else{
                return Response::wrapError($res["msg"]);
            }
        }
    }

    public function cosUploadsMookaVideo(){
        $file = request()->file('file');
        $srcPath = Config::get("objectstorage.mooka_video");//本地文件绝对路径
        try {
            validate(['image'=>'filesize:10240|fileExt:jpg,png,jpeg'])
                ->check([$file]);
            if($file){
                //传临时目录以及mime类型以及创建远程目录
                $res = \app\common\service\CommonObjectStorageService::uploadImages($file->getPathname(),$file->getMime(),$srcPath,$file->extension());

            }else{
                return Response::wrapError($file->getError(),-1);
            }
        } catch (\think\exception\ValidateException $e) {
            return Response::wrapError($file->getError(),-1);
        }
        if (isset($res)){
            $res = (array)json_decode($res);
            if($res["code"] == 0){
                $domain = Config::get("objectstorage.domain_name");
                $res["data"] = str_replace($domain,"/",$res["data"]);
                return Response::wrapData($res["data"]);
            }else{
                return Response::wrapError($res["msg"]);
            }
        }
    }

    //订单评价素材上传接口
    public function cosUploadsIcValueImages(){
        $file = request()->file('file');
        $srcPath = Config::get("objectstorage.user_order_img");//本地文件绝对路径
        try {
            validate(['image'=>'filesize:10240|fileExt:jpg,png,jpeg'])
                ->check([$file]);
            if($file){
                //传临时目录以及mime类型以及创建远程目录
                $res = \app\common\service\CommonObjectStorageService::uploadImages($file->getPathname(),$file->getMime(),$srcPath,$file->extension());

            }else{
                return Response::wrapError($file->getError(),-1);
            }
        } catch (\think\exception\ValidateException $e) {
            return Response::wrapError($file->getError(),-1);
        }
        if (isset($res)){
            $res = (array)json_decode($res);
            if($res["code"] == 0){
                $domain = Config::get("objectstorage.domain_name");
                $res["data"] = str_replace($domain,"/",$res["data"]);
                return Response::wrapData($res["data"]);
            }else{
                return Response::wrapError($res["msg"]);
            }
        }
    }
    //获取表单上传文件
    public function materialUpload(){
        // 获取表单上传文件
        $file = request()->file('image');
        try {
            validate(['image'=>'filesize:1024000|fileExt:jpg,jpeg,png'])->check([$file]);  //最大500kb  也就512000字节
            $savename = \think\facade\Filesystem::disk('public')->putFile( '/uploads/image/material', $file);
        } catch (\Exception $e) {
            return json(['code' => 0, 'msg' => lang($e->getMessage()), 'data' => [], 'count' => '']);
        }
        return json(['code' => 1, 'msg' => lang(''), 'data' => ['img_url'=>$savename], 'count' => '']);
    }
    
    //物料多图片上传
    public function materialUploads(){
        // 获取表单上传文件
        $files = request()->file('images');
        $id =  Request::param('id');
        try {
            validate(['image'=>'filesize:1024000|fileExt:jpg,jpeg,png'])->check($files);  //最大500kb  也就512000字节
            $savename = [];
            foreach($files as $file) {
                $savename = \think\facade\Filesystem::disk('public')->putFile( '/uploads/image/material', $file);
            }
        } catch (\Exception $e) {
            return json(['code' => 0, 'msg' => lang($e->getMessage()), 'data' => [], 'count' => '']);
        }
        return json(['code' => 1, 'msg' => lang(''), 'data' => ['id'=>$id,'img_url'=>$savename], 'count' => '']);
    }

    //订单评价截图上传接口
    public function cosUploadsEstimateImages(){
        $file = request()->file('file');
        $srcPath = Config::get("objectstorage.user_estimate_img");//本地文件绝对路径
        try {
            validate(['image'=>'filesize:10240|fileExt:jpg,png,jpeg'])
                ->check([$file]);
            if($file){
                //传临时目录以及mime类型以及创建远程目录
                $res = \app\common\service\CommonObjectStorageService::uploadImages($file->getPathname(),$file->getMime(),$srcPath,$file->extension());

            }else{
                return Response::wrapError($file->getError(),-1);
            }
        } catch (\think\exception\ValidateException $e) {
            return Response::wrapError($file->getError(),-1);
        }
        if (isset($res)){
            $res = (array)json_decode($res);
            if($res["code"] == 0){
                $domain = Config::get("objectstorage.domain_name");
                $res["data"] = str_replace($domain,"/",$res["data"]);
                return Response::wrapData($res["data"]);
            }else{
                return Response::wrapError($res["msg"]);
            }
        }
    }

    public function cosUploadsCancleImages(){
        $file = request()->file('file');
        $srcPath = Config::get("objectstorage.cancle_img");//本地文件绝对路径
        try {
            validate(['image'=>'filesize:10240|fileExt:jpg,png,jpeg'])
                ->check([$file]);
            if($file){
                //传临时目录以及mime类型以及创建远程目录
                $res = \app\common\service\CommonObjectStorageService::uploadImages($file->getPathname(),$file->getMime(),$srcPath,$file->extension());

            }else{
                return Response::wrapError($file->getError(),-1);
            }
        } catch (\think\exception\ValidateException $e) {
            return Response::wrapError($file->getError(),-1);
        }
        if (isset($res)){
            $res = (array)json_decode($res);
            if($res["code"] == 0){
                $domain = Config::get("objectstorage.domain_name");
                $res["data"] = str_replace($domain,"/",$res["data"]);
                return Response::wrapData($res["data"]);
            }else{
                return Response::wrapError($res["msg"]);
            }
        }
    }



    /**
     * /wxapp/public/part_file
     * identifier:identifier
     * index:分块系号
     * dir:文件上传目录 用于一会合并的目录每次请求接口不一样
     */
    public function part_file()
    {

        $identifier = $this->request->param('identifier');
        $index      = (int)$this->request->param('index');//分块系号
        $dir        = app()->getRootPath() . "/public/uploads/liveVideo_upload_tmp/". $this->request->param('dir') . '/';//文件上传目录
        if (!is_dir($dir)) {
            @mkdir($dir);
        }
        $tmppath = $dir . $identifier . '_' . $index;
        $part    = file_get_contents('php://input');
        file_put_contents($tmppath, $part);//(缓存分块文件 ）
        return Response::wrapData();
    }

    /**
     * /wxapp/public/merge_file
     * identifier:identifier
     * fileName:文件名字
     * dir:刚刚生成的唯一目录
     */
    public function merge_file()
    {
        $identifier = $this->request->param('identifier');
        $type = Request::param("type");//1模卡 2素材
//        $fileName   = $this->request->param('fileName');
        $fileName = strtolower($this->str_random(20)).uniqid();//随机一个存储文件名
        $index      = (int)$this->request->param('index');//分块数
        $dir        = app()->getRootPath() . "/public/uploads/liveVideo_upload_tmp/". $this->request->param('dir') . '/';
        $tmppath    = $dir . $fileName;
        for ($i = 0; $i < $index; $i++) {
            $path   = $dir . $identifier . '_' . $i;
            $binary = file_get_contents($path);
            $res    = file_put_contents($tmppath, $binary, FILE_APPEND);
            if ($res) {
                @unlink($path);
            }//删除缓存分块文件
        }

        $data = ['url' => substr($tmppath, 1)];

        $srcPathFile = $dir.$fileName;
        if($type == 1){
            $srcPath = Config::get("objectstorage.mooka_video");
        }else if($type == 2){
            $srcPath = Config::get("objectstorage.icValueVideo");
        }
        $extension = Request::param("extension","");
        if(empty($extension)){
            $extension = pathinfo($srcPathFile)['extension'];
        }

        $res = \app\common\service\CommonObjectStorageService::uploadImages($srcPathFile,'video/mp4',$srcPath,$extension);
        $res = (array)json_decode($res);
        if($res["code"] == 0){
            $file = $srcPathFile;
            if(file_exists($file)){
                @unlink($file);
            }

            $domain = Config::get("objectstorage.domain_name");
            $res["data"] = str_replace($domain,"/",$res["data"]);
            return Response::wrapData($res["data"]);
        }else{
            return Response::wrapError($res["msg"]);
        }

    }



    public function destroyCosFile(){
        $pic = $this->request->post("file","");
        if(!empty($pic))
        {

            if(strpos($pic,"http")!== false){
                $str = Config::get("objectstorage.domain_name");//本地文件绝对路径
                $pic = str_replace($str,"/",$pic);
            }
            $res = CommonObjectStorageService::delCosFile($pic);
            return Response::wrapData();
        }
    }

    public function str_random($length = 16)
    {
        $string = '';
        while (($len = strlen($string)) < $length) {
            $size = $length - $len;
            $bytes = random_bytes($size);
            $string .= substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size);
        }
        return $string;
    }

}